package com.itheima.health.service.impl;

import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.SetMealDao;
import com.itheima.health.exception.BusinessRuntimeException;
import com.itheima.health.pojo.Order;
import com.itheima.health.service.ReportService;
import com.itheima.health.util.DateUtils;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.rmi.MarshalledObject;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 数据报表service
 */
@Service
@Transactional
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private ReportService reportService;
    @Autowired
    private SetMealDao setMealDao;


    @Override
    public Map<String, Object> getBusinessReportData() throws Exception {
        //获取当前日期
        String today = DateUtils.getDay();
        //获取本周一日期
        String thisWeekMonday = DateUtils.getThisWeekMonday();
        //获取本月第一天的日期
        String firstDayThisMonth = DateUtils.getFirstDayThisMonth();
        //今日新增会员数
        Integer todayNewMember = memberDao.findMemberCountByDate(today);
        //总会员数
        Integer totalMember = memberDao.findTotalMemberCount();
        //本周新增会员数
        Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday);
        //本月新增会员数
        Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDayThisMonth);
        //本日预约数
        Integer todayOrderMember = orderDao.findOrderCountByDate(today);
        //本周预约数
        Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday);
        //本月预约数
        Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDayThisMonth);
        //今日到诊数
        Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);
        //本周到诊数
        Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday);
        //本月到诊数
        Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDayThisMonth);
        //热门套餐
        List<Map> hotSetmeal = orderDao.findHotSetmeal();

        HashMap<String, Object> result = new HashMap<>();
        result.put("reportDate", today);
        result.put("todayNewMember", todayNewMember);
        result.put("totalMember", totalMember);
        result.put("thisWeekNewMember", thisWeekNewMember);
        result.put("thisMonthNewMember", thisMonthNewMember);
        result.put("todayOrderMember", todayOrderMember);
        result.put("thisWeekOrderNumber", thisWeekOrderNumber);
        result.put("thisMonthOrderNumber", thisMonthOrderNumber);
        result.put("todayVisitsNumber", todayVisitsNumber);
        result.put("thisWeekVisitsNumber", thisWeekVisitsNumber);
        result.put("thisMonthVisitsNumber", thisMonthVisitsNumber);
        result.put("hotSetmeal", hotSetmeal);

        return result;
    }

    @Override
    public HashMap<String, Object> getMemberReport() {
        Calendar calendar = Calendar.getInstance();
        // 时间起点定格在十二个月前
        calendar.add(Calendar.MONTH, -11);

        // months
        List<String> months = new ArrayList<>();
        // memberCount
        List<Integer> memberCount = new ArrayList<>();

        // 遍历过去12个月
        for (int i = 0; i < 12; i++) {
            // 获取当前年份
            Integer currentYear = calendar.get(Calendar.YEAR);
            // 获取当前月份
            Integer currentMonth = calendar.get(Calendar.MONTH) + 1;
            // 更新months
            months.add(currentYear + "." + currentMonth);
            // 获取当前月的天数
            Integer currentDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

            // 获取截至目前会员人数
            Integer count = memberDao.selectCountUntillCurrentMonth(currentYear + "-" + currentMonth + "-" + currentDays);
            // 更新memberCount
            memberCount.add(count);

            calendar.add(Calendar.MONTH, 1);
        }

        // 封装返回结果
        HashMap<String, Object> data = new HashMap<>();
        data.put("months", months);
        data.put("memberCount", memberCount);

        return data;
    }

    @Override
    public XSSFWorkbook exportBusinessReport() {
        //创建工作簿
        File file = new File("src/main/resources/report_template.xlsx");
        InputStream is = null;
        try {
            is = new FileInputStream(file);
            Map<String, Object> businessReport = reportService.getBusinessReportData();
            // 获取各项数据
            String reportDate = (String) businessReport.get("reportDate");
            Integer todayNewMember = (Integer) businessReport.get("todayNewMember");
            Integer thisWeekNewMember = (Integer) businessReport.get("thisWeekNewMember");
            Integer thisMonthNewMember = (Integer) businessReport.get("thisMonthNewMember");
            Integer totalMember = (Integer) businessReport.get("totalMember");
            Integer todayOrderMember = (Integer) businessReport.get("todayOrderMember");
            Integer thisWeekOrderNumber = (Integer) businessReport.get("thisWeekOrderNumber");
            Integer thisMonthOrderNumber = (Integer) businessReport.get("thisMonthOrderNumber");
            Integer todayVisitsNumber = (Integer) businessReport.get("todayVisitsNumber");
            Integer thisWeekVisitsNumber = (Integer) businessReport.get("thisWeekVisitsNumber");
            Integer thisMonthVisitsNumber = (Integer) businessReport.get("thisMonthVisitsNumber");
            List<Map> hotSetmeal = (List<Map>) businessReport.get("hotSetmeal");


            XSSFWorkbook workbook = new XSSFWorkbook(is);
            //获取工作表，既可以根据工作表的顺序获取，也可以根据工作表的名称获取
            XSSFSheet sheet = workbook.getSheetAt(0);
            // 报告日期
            XSSFCell reportDateCell = sheet.getRow(2).getCell(5);
            // 新增会员数
            XSSFCell todayNewMemberCell = sheet.getRow(4).getCell(5);
            // 本周新增会员数
            XSSFCell thisWeekNewMemberCell = sheet.getRow(5).getCell(5);
            // 本月新增会员数
            XSSFCell thisMonthNewMemberCell = sheet.getRow(5).getCell(7);        // 本月新增会员数
            // 总会员数
            XSSFCell totalMemberCell = sheet.getRow(4).getCell(7);

            // 今日预约数
            XSSFCell todayOrderNumberCell = sheet.getRow(7).getCell(5);
            // 本周预约数
            XSSFCell thisWeekOrderNumberCell = sheet.getRow(8).getCell(5);
            // 本月预约数
            XSSFCell thisMonthOrderNumberCell = sheet.getRow(9).getCell(5);
            // 今日到诊数
            XSSFCell todayVisitsNumberCell = sheet.getRow(7).getCell(7);
            // 本周到诊数
            XSSFCell thisWeekVisitsNumberCell = sheet.getRow(8).getCell(7);
            // 本月到诊数
            XSSFCell thisMonthVisitsNumberCell = sheet.getRow(9).getCell(7);

            // 报告日期赋值
            reportDateCell.setCellValue(reportDate);
            // 会员统计赋值
            todayNewMemberCell.setCellValue(todayNewMember);
            thisWeekNewMemberCell.setCellValue(thisWeekNewMember);
            thisMonthNewMemberCell.setCellValue(thisMonthNewMember);
            totalMemberCell.setCellValue(totalMember);
            // 预约到诊赋值
            todayOrderNumberCell.setCellValue(todayOrderMember);
            thisWeekOrderNumberCell.setCellValue(thisWeekOrderNumber);
            thisMonthOrderNumberCell.setCellValue(thisMonthOrderNumber);
            todayVisitsNumberCell.setCellValue(todayVisitsNumber);
            thisWeekVisitsNumberCell.setCellValue(thisWeekVisitsNumber);
            thisMonthVisitsNumberCell.setCellValue(thisMonthVisitsNumber);

            // 热门套餐赋值
            // 动态扩容并插入
            Integer row = 12;
            for (Map map : hotSetmeal) {
                String name = map.get("name").toString();
                String setmeal_count = map.get("setmeal_count").toString();
                String proportion = map.get("proportion").toString();
                // 处理动态扩容
                if (row >= sheet.getLastRowNum()) {
                    // 新增行
                    sheet.createRow(row + 1);
                    // 复制样式
                    sheet.copyRows(row, row, row + 1, new CellCopyPolicy());
                }
                // 表格填值
                sheet.getRow(row).getCell(4).setCellValue(name);
                sheet.getRow(row).getCell(5).setCellValue(setmeal_count);
                sheet.getRow(row).getCell(6).setCellValue(proportion);
                row++;
            }
            return workbook;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessRuntimeException("excel业务失败");
        }
    }

    @Override
    public HashMap<String, Object> getSetmealReport() {
        // 构造结果map
        HashMap<String, Object> data = new HashMap<>();
        // 构造mapsetmealNames字段
        ArrayList<String> setmealNames = setMealDao.getSetmealNames();
        // 查询所有的套餐项及对应的被预约次数
        List<Map> setmealCount = new ArrayList<>();
        for (String setmealName : setmealNames) {
            Map map = new HashMap();
            map.put("name", setmealName);
            map.put("value", orderDao.getSetmealCountBySetmealName(setmealName));
            setmealCount.add(map);
        }

        // 封装setmealNames与setmealCount
        data.put("setmealNames", setmealNames);
        data.put("setmealCount", setmealCount);

        // 返回结果e
        return data;
    }


}
